#include "device_info.h"            // 引入设备信息模块头文件
#include <HTTPClient.h>           // 用于 HTTP 上传
#include "mbedtls/md.h"           // 用于 HMAC-SHA256 签名
#include "esp_system.h"     // 用于 esp_read_mac() 与 ESP_MAC_WIFI_STA
#include <Arduino.h>


// ------------------------- 全局变量 -------------------------
String g_phoneIP = "";                         // 临时存储手机IP（每次连接下发）
String g_activationUID = "";                   // 设备激活UID（微信UID）
bool   g_touchAuth = false;                    // 触摸授权标志
String g_touchExpireAt = "";                   // 授权截止时间（如30天/永久）

const char* SECRET_KEY = "ChiYu2025SecretKey"; // HMAC签名密钥（用于数据完整性校验）

// ------------------------- 获取MAC地址 -------------------------
// ------------------------- 获取MAC地址 -------------------------
String getMacAddress() {
  return WiFi.macAddress();  // ✅ 使用 WiFi 库自带函数
}


// ------------------------- 生成设备名称 -------------------------
String getDeviceName() {
  String mac = getMacAddress();                // 获取设备MAC地址
  return "chiyu_" + mac.substring(mac.length() - 4); // 名称格式：chiyu_xxxx
}

// ------------------------- HMAC-SHA256签名 -------------------------
String hmacSign(const String &payload) {
  byte hash[32];                               // 定义哈希输出缓冲
  mbedtls_md_context_t ctx;                    // 初始化加密上下文
  mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; // 使用SHA256算法
  mbedtls_md_init(&ctx);                       // 初始化上下文
  mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1); // 设置算法
  mbedtls_md_hmac_starts(&ctx, (const unsigned char*)SECRET_KEY, strlen(SECRET_KEY)); // 设置密钥
  mbedtls_md_hmac_update(&ctx, (const unsigned char*)payload.c_str(), payload.length()); // 输入数据
  mbedtls_md_hmac_finish(&ctx, hash);          // 完成计算
  mbedtls_md_free(&ctx);                       // 释放资源

  String result;                               // 定义结果字符串
  for (int i = 0; i < 32; i++) {               // 将哈希结果转为十六进制字符串
    char b[3];
    sprintf(b, "%02x", hash[i]);
    result += b;
  }
  return result;                               // 返回签名字符串
}


// ------------------------- 设置激活UID -------------------------
void setActivationUID(const String &uid) {
  g_activationUID = uid;                       // 存储微信UID（激活后不可为空）
  Serial.println("[INFO] 设备绑定UID: " + uid);// 打印绑定状态
}

// ------------------------- 设置触摸授权 -------------------------
void setTouchAuth(bool enable, const String &expireAt) {
  g_touchAuth = enable;                        // 设置触摸是否授权
  g_touchExpireAt = expireAt;                  // 设置授权截止时间
  Serial.printf("[INFO] 触摸授权：%s 截止：%s\n", enable ? "开启" : "关闭", expireAt.c_str()); // 打印状态
}

// ------------------------- 生成设备信息JSON -------------------------
String getDeviceInfoJSON() {
  String mac = getMacAddress();                // 获取MAC地址
  String name = getDeviceName();               // 生成设备名
  String nonce = String(random(100000, 999999)); // 随机数防重放攻击
  unsigned long ts = millis();                 // 当前时间戳（毫秒）
  String signature = hmacSign(mac + g_activationUID + nonce + String(ts)); // 生成签名校验值

  DynamicJsonDocument doc(600);                // 创建JSON文档
  doc["device_name"] = name;                   // 设备名称
  doc["device_id"] = mac;                      // 设备唯一ID
  doc["firmware_ver"] = "v1.0.0";              // 固件版本号
  doc["hardware_rev"] = "C3-Display-RevA";     // 硬件版本号
  doc["activation_uid"] = g_activationUID;     // 激活UID
  doc["touch_authorized"] = g_touchAuth;       // 触摸授权开关
  doc["touch_expire_at"] = g_touchExpireAt;    // 触摸授权到期时间
  doc["secure_nonce"] = nonce;                 // 安全随机数
  doc["timestamp"] = ts;                       // 时间戳
  doc["check_sum"] = signature;                // 数据签名校验
  doc["uptime_ms"] = millis();                 // 系统运行时长
  doc["connect_type"] = WiFi.isConnected() ? "WiFi" : "AP"; // 当前连接类型
  doc["signal_strength"] = WiFi.RSSI();        // 信号强度（RSSI）
  doc["device_ip"] = WiFi.localIP().toString();// 当前设备IP地址

  String json;                                 // 定义输出字符串
  serializeJson(doc, json);                    // 序列化为JSON字符串
  return json;                                 // 返回结果
}

// ------------------------- 上传设备信息到手机 -------------------------
bool uploadDeviceInfoToServer() {
  if (g_phoneIP == "") {                       // 检查是否已设置手机IP
    Serial.println("[HTTP] 未设置手机IP，跳过上报");
    return false;
  }

  if (WiFi.status() != WL_CONNECTED) {         // 检查WiFi连接状态
    Serial.println("[HTTP] WiFi未连接");
    return false;
  }

  String url = "http://" + g_phoneIP + ":8080/device/report"; // 拼接上报目标URL
  Serial.println("[HTTP] 上报目标: " + url);  // 输出目标地址

  HTTPClient http;                             // 创建HTTP客户端
  http.begin(url);                             // 启动连接
  http.addHeader("Content-Type", "application/json"); // 设置请求头

  String payload = getDeviceInfoJSON();        // 获取上报数据（JSON）
  int code = http.POST(payload);               // 发送POST请求

  if (code > 0) {                              // 如果返回状态有效
    Serial.printf("[HTTP] 上报完成，状态码: %d\n", code);
    Serial.println("[HTTP] 响应: " + http.getString());
  } else {                                     // 否则输出错误信息
    Serial.printf("[HTTP] 上报失败: %s\n", http.errorToString(code).c_str());
  }

  http.end();                                  // 关闭HTTP连接
  return (code == 200);                        // 返回是否成功
}
